﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpHomeEngine;

namespace Insteon.Devices
{
    //light on
//141028.975  0003 StandardMessage      (to:00.00.01) (fr:18.80.87) (Flags: AllLinkBroadcast False 2 3) (c1:11 c2: 0)     : 02 50 18 80 87 00 00 01 cb 11 00  Unsolicited
//141029.173  0004 StandardMessage      (to:AA.AA.AA) (fr:18.80.87) (Flags: ALLLinkCleanup   False 0 1) (c1:11 c2: 1)     : 02 50 18 80 87 aa aa aa 41 11 01  Unsolicited

    //light off     
//141033.892  0005 StandardMessage      (to:00.00.01) (fr:18.80.87) (Flags: AllLinkBroadcast False 2 3) (c1:13 c2: 0)     : 02 50 18 80 87 00 00 01 cb 13 00  Unsolicited 
//141034.093  0006 StandardMessage      (to:AA.AA.AA) (fr:18.80.87) (Flags: ALLLinkCleanup   False 0 1) (c1:13 c2: 1)     : 02 50 18 80 87 aa aa aa 41 13 01  Unsolicited
    


    public class LampLinc : InsteonDevice
    {
        TagByte Dimmer;
        TagByte RampRate; //not supported for direct commands :-( Disappointing
        TagBoolean On;
        Messages.Insteon.StandardMessage LastStdMessage;
        byte[] ThrowAwayDupeCommands = new byte[5] { 0x11, 0x12, 0x13, 0x14, 0x18 };

        public LampLinc(InsteonInterface Interface, string Name, InsteonAddress Address)
            : base(Interface, Name, Address)
        {
            Dimmer = new TagByte(Interface, this, "Dimmer");
            RampRate = new TagByte(Interface, this, "RampRate");
            On = new TagBoolean(Interface, this, "On");
        }

        internal override Commands.Command GenerateStateChangeCommand(Tag Tag, object Value)
        {
            if (Tag == Dimmer)
            {
                byte Byte;
                try
                {
                    Byte = (byte) Value;
                }
                catch(Exception E)
                {
                    return null;
                }
                Commands.Insteon.StandardCommand Command = new Commands.Insteon.StandardCommand(this.InsteonAddress, 0x11, Byte);
                return Command;
            }
            if (Tag == RampRate)
            {
                byte Byte;
                try
                {
                    Byte = (byte)Value;
                }
                catch (Exception E)
                {
                    return null;
                }
                Commands.Insteon.StandardCommand Command = new Commands.Insteon.StandardCommand(this.InsteonAddress, 0x26, Byte);
                return Command;
            }
            if (Tag == On)
            {
                Boolean Bool;
                try
                {
                    Bool = (Boolean)Value;
                }
                catch (Exception E)
                {
                    return null;
                }
                Commands.Insteon.StandardCommand Command = null;
                if (Bool == true)
                {
                    Command = new Commands.Insteon.StandardCommand(this.InsteonAddress, 0x11, 0x00);
                }
                else
                {
                    Command = new Commands.Insteon.StandardCommand(this.InsteonAddress, 0x13, 0x00);
                }
                return Command;
            }
            return null;
        }


        internal override void HandleUnsolicitedMessage(Messages.Message Message)
        {
            if (!(Message is Messages.Insteon.StandardMessage))
            {
                return;
            }
            Messages.Insteon.StandardMessage Mess = (Messages.Insteon.StandardMessage)Message;
            if (Mess.From != this.InsteonAddress)
            {
                return;
            }

            if (LastStdMessage != null)
            {
                if (LastStdMessage.Command1 == Mess.Command1)
                {
                    if (ThrowAwayDupeCommands.Contains(LastStdMessage.Command1))
                    {
                        if (Mess.ReceivedTime.Subtract(LastStdMessage.ReceivedTime).Milliseconds < 500)
                        {
                            LastStdMessage = Mess;
                            //Console.WriteLine("Device Dupe Drop");
                            return; //ignore dupes
                        }
                    }
                }
            }

            LastStdMessage = Mess;

            if (Mess.Command1 == 0x11 || Mess.Command1 == 0x12)
            {
                UnsolicitedTagChange(On, true);
                if (Mess.Command1 == 0x14)
                {
                    RaiseDeviceEvent("fast on", On, true);
                }
            }
            if (Mess.Command1 == 0x13 || Mess.Command1 == 0x14)
            {
                UnsolicitedTagChange(On, false);
                if (Mess.Command1 == 0x14)
                {
                    RaiseDeviceEvent("fast off", On, true);
                }
            }
            if (Mess.Command1 == 0x17)
            {
                //light start manual change
                if (Mess.Command2 == 0x00)
                {
                    //going down
                }
                if (Mess.Command2 == 0x01)
                {
                    //going up
                }
            }
            if (Mess.Command2 == 0x18)
            {
                //light stop manual change
            }
        }

        internal override Commands.Command GenerateStateRequest(Tag Tag)
        {
            if (Tag == Dimmer)
            {
                Commands.Insteon.StandardCommand Command = new Commands.Insteon.StandardCommand(this.InsteonAddress, 0x19, 0x00);
                return Command;
            }
            return null;
        }


        internal override object ReadStateRequestResponse(Commands.Command Command, Tag Tag)
        {
            if (Command.DeviceResponse == null)
            {
                return null;
            }
            if (!(Command.DeviceResponse is Messages.Insteon.StandardMessage)){
                return null;
            }
            Messages.Insteon.StandardMessage Message = (Messages.Insteon.StandardMessage)Command.DeviceResponse;
            if (Tag == Dimmer)
            {
                Command.Value = Dimmer.CastValue(Message.Command2);
                return Command.Value;
            }
            if (Tag == On)
            {
                if (Message.Command1 == 0x11)
                {
                    Command.Value = true;
                    return true;
                }
                if (Message.Command2 == 0x13)
                {
                    Command.Value = false;
                    return false;
                }
            }
            return null;
        }
    }
}
